<template>
    <el-dialog v-bind="dialogProps" :visible.sync="visible" :destroy-on-close="false"
               @open="handleOpen" @opened="handleOpened"
               @close="handleClose" @closed="handleClosed" v-dialog-drag>
        <template slot="title">
            <virtual-node :render="titleSlot" />
        </template>
        <template v-if="component">
            <components v-if="showComponent" :is="component" v-bind="componentProps"
                        :ref="componentRef" v-get-ref="getRefFn"
                        @event="handleComponentEvent" />
        </template>
        <template v-else>
            <virtual-node :render="content" />
        </template>
        <template slot="footer" v-if="showFooter">
            <template v-if="buttons">
                <buttons :data="buttons" @event="handleButtonEvent" />
            </template>
            <template v-else>
                <virtual-node :render="footerSlot" />
            </template>
        </template>
    </el-dialog>
</template>

<script>
import Vue from 'vue';
import inject from "@common/mixins/inject";
import { Dialog } from 'element-ui';
import { ElDialog } from "@common/components/custom/attributes";

export default {
    extends: inject,
    components: {
        ElDialog: Dialog,
        Buttons: () => import("./buttons"),
        VirtualNode: Vue.extend({
            functional: true,
            props: {
                render: Function,
            },
            render(h, ctx) {
                if (typeof ctx.props.render === 'function') {
                    return ctx.props.render(h, ctx.parent);
                }
            },
        }),
    },
    inheritAttrs: true,
    props: {
        dialogProps: {
            type: Object,
            default() {
                return ElDialog;
            },
        },
        open: {
            type: Function,
            default() {
                return () => {
                }
            }
        },
        opened: {
            type: Function,
            default() {
                return () => {
                }
            }
        },
        close: {
            type: Function,
            default() {
                return () => {
                }
            }
        },
        closed: {
            type: Function,
            default() {
                return () => {
                }
            }
        },
        content: {
            type: Function,
            default() {
                return () => {
                    return <span />;
                }
            }
        },
        titleSlot: {
            type: Function,
            default() {
                return () => this.title
            }
        },
        footerSlot: {
            type: Function,
            default() {
                return () => {
                }
            }
        },
        data: {
            type: Object,
            default: null
        },
        showFooter: {
            type: Boolean,
            default: true
        },
        component: {
            type: [Object, Function],
            default: null
        },
        componentRef: {
            type: String,
            default: 'component',
        },
        componentProps: {
            type: Object,
            default: null
        },
        componentEvent: {
            type: Function,
            default: null,
        },
        buttons: {
            type: Array,
            default: null,
        },
        dialogDrag: {
            type: Boolean,
            default: true
        },
    },
    data() {
        return {
            showComponent: false,
            visible: false,
            skipProps: [ 'open', 'opened', 'close', 'closed', 'content', 'titleSlot', 'footerSlot',
                'data', 'showFooter', 'component', 'componentRef', 'componentProps',
                'componentEvent', 'buttons', 'dialogDrag' ],
        };
    },
    methods: {
        getRefFn(c) {
            let ref = this.componentRef || 'component';
            typeof this.setChildrenRef === 'function' && this.setChildrenRef(ref, c);
        },
        handleOpen() {
            this.showComponent = true;
            typeof this.open === 'function' && this.open(this);
        },
        handleOpened() {
            typeof this.opened === 'function' && this.opened(this);
        },
        handleClose() {
            typeof this.close === 'function' && this.close(this);
        },
        handleClosed() {
            this.showComponent = false;
            typeof this.closed === 'function' && this.closed(this);
        },
        handleButtonEvent(event) {
            if (event.type === 'click' && event.item && typeof event.item.click === 'function') {
                event.item.click(this, this.$refs);
            }
        },
        handleComponentEvent(event) {
            if (event === 'closeDialog') {
                this.visible = false;
                if (typeof this.componentEvent === 'function') {
                    this.componentEvent({
                        type: 'closeEvent',
                    }, this);
                }
                return;
            }
            if (typeof this.componentEvent === 'function') {
                this.componentEvent(event, this, this.$refs);
            }
        },
    },
}
</script>

<style>
</style>
